package com.kf.config;

import com.kf.aop.SysLogAspect;
import com.kf.handler.MyException;
import com.kf.mapper.LogErrorMapper;
import com.kf.mapper.LogSysOperationMapper;
import com.kf.pojo.LogError;
import com.kf.pojo.LogSysOperation;
import com.kf.pojo.User;
import com.kf.util.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolationException;
import java.sql.SQLException;
import java.sql.SQLIntegrityConstraintViolationException;

/**
 * 常见异常处理程序
 *
 * @author Honey
 * @date 2022/12/23
 */
@RestControllerAdvice
public class CommonExceptionHandler {

    @Resource
    LogErrorMapper logErrorMapper;

    @Resource
    LogSysOperationMapper logSysOperationMapper;

    private static final Logger logger = LoggerFactory.getLogger(CommonExceptionHandler.class);

    @ExceptionHandler({MethodArgumentNotValidException.class})
    @ResponseStatus(HttpStatus.OK)
    @Order(2)
    public R handleMethodArgumentNotValidException(MethodArgumentNotValidException ex) {
        BindingResult bindingResult = ex.getBindingResult();

        String defaultMessage=null;
        for (FieldError fieldError : bindingResult.getFieldErrors()) {
            defaultMessage= fieldError.getDefaultMessage();
        }


       return R.error(defaultMessage);
    }

    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler({ConstraintViolationException.class})
    @Order(3)
    public R handleConstraintViolationException(ConstraintViolationException ex) {
        System.out.println("捕获到了异常1");
        return R.error("数据约束有误");
    }
    @ExceptionHandler(MyException.class)
    @ResponseStatus(HttpStatus.OK)
    @Order(4)
    public R handleRenException(MyException ex){
        System.out.println("我被捕获到了自定义异常");
        saveLog(ex);
        return R.error(ex.getCode(), ex.getMsg());
    }

    @ExceptionHandler(SQLIntegrityConstraintViolationException.class)
    @ResponseStatus(HttpStatus.OK)
    @Order(5)
    public R sQLIntegrityConstraintViolationException(SQLIntegrityConstraintViolationException ex){
        System.out.println("我被捕获到了sql异常");
        saveLog(ex);
        return R.error(ResultCode.FAIL.getCode(), ex.getMessage());
    }
    @Order(6)
    @ExceptionHandler(NullPointerException.class)
    public R nullPointerException(NullPointerException ex){
        logger.error(ex.getMessage(), ex);

        saveLog(ex);
        System.out.println("我是空指针异常");
        return R.error();
    }
    @Order(7)
    @ExceptionHandler(SQLException.class)
    public R exception(SQLException ex){
        logger.error(ex.getMessage(), ex);

        saveLog(ex);
        System.out.println("我是sql异常");
        return R.error(ResultCode.SHUJU_ADD_ERROR3);
    }



    /**
     * 保存异常日志
     */
    private void saveLog(Exception ex){
        LogError log = new LogError();
        LogSysOperation logSysOperation = SysLogAspect.stringThreadLocal1.get();
        SysLogAspect.stringThreadLocal1.remove();
        //请求相关信息
        //异常信息
        HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
        assert request != null;
        log.setIp(request.getServerName() + ":" + request.getServerPort());
        log.setRequestUri(request.getRequestURI());
        log.setRequestMethod(request.getMethod());
        log.setRequestParams(logSysOperation.getRequestParams());
        User user = SecurityUser.getUser();
        System.out.println("异常日志 用户名："+user.getUsername());
        log.setRequestUser(user.getUsername());
        log.setErrorInfo(ExceptionUtils.getErrorStackTrace(ex));
        //保存
        logErrorMapper.insert(log);
        System.out.println(logSysOperation);
        logSysOperation.setOperation(logSysOperation.getOperation());
        logSysOperation.setStatus(0);
        logSysOperation.setRequestTime(logSysOperation.getRequestTime());
        logSysOperation.setIp(logSysOperation.getIp());
        logSysOperation.setRequestMethod(logSysOperation.getRequestMethod());
        String requestParams = logSysOperation.getRequestParams();
        logSysOperation.setRequestParams(requestParams);
        String requestUri = logSysOperation.getRequestUri();
        logSysOperation.setRequestUri(requestUri);
        logSysOperation.setRequestUser(logSysOperation.getRequestUser());
        logSysOperationMapper.insert(logSysOperation);

    }


}